/**
 * TO BE DETERMINED
 */
package org.eichar.server.service;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.SQLException;
import java.util.Properties;
import java.util.Random;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eichar.client.shared.Language;
import org.eichar.client.shared.ServiceCommunicationConstants;
import org.eichar.client.shared.Word;
import org.eichar.server.database.DatabaseAccess;
import org.eichar.server.i18n.Messages;

import com.google.inject.Inject;

/**
 * Servlet that reads questions from the database and responds with a
 * {@link Properties} object written as XML to the response. The order of the
 * properties is not specified. The response is as follows:
 * 
 * 
 * @author Jesse
 */
public class QuestionService extends HttpServlet {

    private static final long serialVersionUID = -2331734535239902767L;

    private DatabaseAccess databaseAccess;

    private Random random;

    /**
     * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        QuestionType requestQuestionType = QuestionType
                .value(request
                        .getParameter(ServiceCommunicationConstants.QUERY_KEY_QUESTION_TYPE));
        String fromLanguageCode = request
                .getParameter(ServiceCommunicationConstants.QUERY_KEY_FROM_LANGUAGE);
        String toLanguageCode = request
                .getParameter(ServiceCommunicationConstants.QUERY_KEY_TO_LANGUAGE);

        Language fromLanguage = Language.getLanguage(fromLanguageCode);
        Language toLanguage = Language.getLanguage(toLanguageCode);

        try {
            Properties properties = new Properties();
            switch (requestQuestionType) {
            case RANDOM:
                getRandomQuestion(properties, fromLanguage, toLanguage);
                break;

            case TRANSLATION:
                getTranslationsQuestion(properties, fromLanguage, toLanguage);
                break;
            default:

                return;
            }
            ServletOutputStream outputStream = response.getOutputStream();
            properties.storeToXML(outputStream, "QuestionProperties"); //$NON-NLS-1$
        } catch (SQLException e) {
            StringBuilder error = new StringBuilder(Messages
                    .getString("QuestionService.sqlException")); //$NON-NLS-1$

            StringWriter writer = new StringWriter();
            e.printStackTrace(new PrintWriter(writer));
            error.append(writer.getBuffer().toString());

            response.getOutputStream().write(error.toString().getBytes());
            return;
        }
    }

    private void getTranslationsQuestion(Properties properties,
            Language fromLanguage, Language toLanguage) throws SQLException {
        properties.put(ServiceCommunicationConstants.RETURN_KEY_QUESTION_TYPE,
                ServiceCommunicationConstants.VALUE_TRANSLATION_QUESTION);

        int translationCount = databaseAccess.getTranslationCount(fromLanguage,
                toLanguage);

        int questionIndex = random.nextInt(translationCount);

        Word[] words = databaseAccess.getTranslation(questionIndex,
                fromLanguage, toLanguage);

        properties.put(ServiceCommunicationConstants.RETURN_FROM_WORD, words[0]
                .getWord());
        properties.put(ServiceCommunicationConstants.RETURN_TO_WORD, words[1]
                .getWord());
    }

    private void getRandomQuestion(Properties properties,
            Language fromLanguage, Language toLanguage) throws SQLException {

        // currently the only type is translation so call getTranslation
        getTranslationsQuestion(properties, fromLanguage, toLanguage);

    }

    @Inject
    public final void setDatabaseAccess(DatabaseAccess databaseAccess) {
        this.databaseAccess = databaseAccess;

    }

    /**
     * @param random
     *            the random to set
     */
    @Inject
    public final void setRandom(Random random) {
        this.random = random;
    }
}
